/* Copyright ©北京微利宝信息技术有限公司 right reserved.*/

package com.wlb365.doc.cfca;

import cn.hutool.core.codec.Base64;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.util.Enumeration;

/**
 * <p>
 * 概述： 秘钥获取工具
 * </p>
 *
 * @author 创建人：    ryl
 * @copyRight 所有权©：  北京微利宝信息技术有限公司  All right reserved.
 * @date 创建时间：2018年8月17日 下午5:44:19
 */
@Slf4j
public class KeyUtils {
    private static final String PRIVATE_PATH = "D:/workspace/scfp/src/main/resources/ht/pfx/";
    private static final String PUBLIC_PATH = "D:/workspace/scfp/src/main/resources/ht/cer/";
    private static final String PRIVATE_PFX = "JFJT.pfx";
    private static final String PUBLIC_CER = "JFJT.cer";
    private static final String PASSWORD = "111111";
    private static final String KEY_STORE_TYPE = "PKCS12";

    /**
     * <p>
     * 概述： 获取私钥别名等信息
     * </p>
     *
     * @param filePath 证书文件地址
     * @param password 证书密码
     * @return String
     * @author ryl
     * @date 2018年8月18日 下午3:10:50
     */
    public static String getPrivateKey(String filePath, String password) {
        String privateKey = null;
        String keyAlias = null;
        try {
            KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
            FileInputStream fileInputStream = new FileInputStream(filePath);
            char[] nPassword = null;
            if ((password == null) || password.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = password.toCharArray();
            }
            keyStore.load(fileInputStream, nPassword);
            fileInputStream.close();
            log.debug("keystore type=" + keyStore.getType());
            Enumeration<String> enumeration = keyStore.aliases();
            if (enumeration.hasMoreElements()) {
                keyAlias = (String) enumeration.nextElement();
                log.debug("alias=[" + keyAlias + "]");
            }
            log.debug("is key entry=" + keyStore.isKeyEntry(keyAlias));
            PrivateKey prikey = (PrivateKey) keyStore.getKey(keyAlias, nPassword);
            Certificate cert = keyStore.getCertificate(keyAlias);
            PublicKey pubkey = cert.getPublicKey();
            log.debug("================================ 分割========================================\n");
            log.debug("秘钥提取地址  ==> " + filePath);
            log.debug("加签公钥提取  ==> " + Base64.encode(pubkey.getEncoded()));
            log.debug("加签私钥提取  ==> " + Base64.encode(prikey.getEncoded()));
            log.debug("================================ 分割========================================\n");
            //log.debug("cert = " + cert);
            privateKey = Base64Util.encodeByte(prikey.getEncoded());
        } catch (Exception e) {
            log.warn("获取私钥失败", e.getMessage(), e);
            e.printStackTrace();
        }
        return privateKey;
    }

    /**
     * <p>
     * 概述： 读取公钥cer
     * </p>
     *
     * @param filePath .cer文件的路径 如：c:/abc.cer
     * @return String base64后的公钥串  公钥
     * @throws Exception
     * @author ryl
     * @date 2018年8月17日 下午6:36:03
     */
    public static String getPublicKey(String filePath) {
        String result = "";
        try {
            @SuppressWarnings("resource")
            InputStream in = new FileInputStream(filePath);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int ch;
            while ((ch = in.read()) != -1) {
                out.write(ch);
            }
            result = Base64Util.encodeByte(out.toByteArray());
            log.debug("核签公钥提取：" + result);
        } catch (IOException e) {
            log.warn("获取公钥失败,文件不存在：", e.getMessage(), e);
            e.printStackTrace();
        } catch (Exception e) {
            log.warn("编码异常：", e.getMessage(), e);
            e.printStackTrace();
        }
        return result;
    }
}